<template>
	<div class="default-main">

		<cus-form id="topic-form" collapsable icon="fa fa-search" label="搜索">
			<template #title-after>
				<el-button icon="el-icon-Search" size="small" type="primary" @click.stop="handleSearch">
					搜索
				</el-button>
				<el-button icon="el-icon-Refresh" size="small" type="primary" @click.stop="resetSearch">
					重置
				</el-button>
			</template>
			<template #form>
				<el-form ref="itemSearchForm" :model="params" label-width="auto">
					<el-row :gutter="20" justify="space-between">
						<el-col :span="8">
							<el-form-item label="话题类型">
								<business-code-select v-model="params.type_eq" :filterable="false" clearable code-type="topicType" filterable force-string-value
								                      placeholder="不限" @change="handleSearch"/>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="标题">
								<el-input v-model="params.title_like" clearable placeholder="模糊查询" @keyup.enter="handleSearch"></el-input>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="内容">
								<el-input v-model="params.content_like" clearable placeholder="模糊查询" @keyup.enter="handleSearch"></el-input>
							</el-form-item>
						</el-col>
					</el-row>
					<el-row :gutter="20" justify="start">
						<el-col :span="8">
							<el-form-item label="用户昵称">
								<el-input v-model="params.nickname_like" :disabled="params.onlyMe" clearable placeholder="模糊查询"
								          @keyup.enter="handleSearch"></el-input>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="状态">
								<business-code-radio v-model="params.isClosed_eq" border code-type="topicClosed" force-string-value @change="handleSearch"/>
							</el-form-item>
						</el-col>
					</el-row>
				</el-form>
			</template>
		</cus-form>

		<cus-table-title id="topic-table-title" icon="el-icon-ChatLineSquare" label="话题列表">
			<template #after>
				<el-tooltip :disabled="!isVisitor()" :hide-after="0" :show-after="500"
				            content="游客模式下，无法发布新话题，请注册账号后使用~"
				            effect="dark" placement="top">
					<el-button :disabled="isVisitor()" icon="el-icon-Plus" size="small" style="margin-left: 20px" type="primary" @click="toAdd">
						发布新话题
					</el-button>
				</el-tooltip>
				<el-button icon="el-icon-ArrowDown" size="small" type="primary"
				           @click="showAllComment">
					展开全部评论
				</el-button>
				<el-button icon="el-icon-ArrowUp" size="small" type="primary" @click="hideAllComment">
					收起全部评论
				</el-button>
				<el-form-item label="排序方式" size="small" style="float: right; margin: 0 0 0 50px">
					<business-code-select v-model="params.sortOrder" :clearable="false" :filterable="false" code-type="topicSortOrder" style="width: 150px"
					                      @change="pageRef.reload()"/>
				</el-form-item>
				<el-form-item label="只看我的" size="small" style="float: right;margin: 0 0 0 50px">
					<el-switch v-model="params.onlyMe" @change="onlyMeChanged"/>
				</el-form-item>
			</template>
		</cus-table-title>
		<el-table ref="topicTableRef" v-loading="topicTableLoading" :data="tableData" :max-height="tableMaxHeight" border class="cus-table" fit
		          max-height="800" row-class-name="topic-row" row-key="id">
			<el-table-column align="center" label="序号" width="60">
				<template v-slot="scope">
					{{ initTableIndex(pageRef, scope.$index) }}
				</template>
			</el-table-column>
			<el-table-column align="center" label="展开评论" type="expand" width="100">
				<template #default="{row: topicRow}">
					<div style="margin: 20px 5%">
						<el-switch v-model="topicRow.onlyMe" active-text="与我相关" style="margin-bottom: 10px"
						           @change="replyOnlyMeChanged(topicRow.onlyMe, topicRow.id)"></el-switch>
						<el-table v-loading="replyTableLoading[topicRow.id]" :border="isAdmin()"
						          :data="topicRow.replyList" :show-header="isAdmin() && topicRow.replyList && topicRow.replyList.length > 0" empty-text="没有评论" fit
						          highlight-current-row max-height="800" row-class-name="comment-row" size="small">
							<el-table-column align="center" label="" min-width="200">
								<template v-slot="{row: commentRow}">
									<div style="display: flex;justify-content: center;align-items: end">
										<el-popover :persistent="false" :show-after="300" placement="left" trigger="hover" width="450">
											<template #reference>
												<el-image :src="handleAvatarUrl(commentRow.avatar) || IMAGE_URL.defaultAvatar"
												          style="margin-right: 5px;cursor: pointer;width: auto;height: 25px;border-radius: 5px"/>
											</template>
											<user-card :user-id="commentRow.userId"></user-card>
										</el-popover>
										<div v-if="commentRow.isAdmin" style="padding-top: 10px;margin-right:40px">
											<el-badge :style="{color: commentRow.nickname === userStore.nickname ? 'var(--el-color-primary)' : undefined}" value="管理员">
												{{ nicknameFilter(commentRow.nickname) }}
											</el-badge>
										</div>
										<div v-else :style="{color: commentRow.nickname === userStore.nickname ? 'var(--el-color-primary)' : undefined}">
											{{ nicknameFilter(commentRow.nickname) }}
										</div>
										<div v-if="commentRow.parentId > 0" style="display: flex;justify-content: center;align-items: end">
											<div>&nbsp;&nbsp;回复&nbsp;&nbsp;</div>
											<el-popover :persistent="false" :show-after="300" placement="left" trigger="hover" width="450">
												<template #reference>
													<el-image :src="handleAvatarUrl(commentRow.replyToAvatar) || IMAGE_URL.defaultAvatar"
													          style="margin-right: 5px;cursor: pointer;width: auto;height: 25px;border-radius: 5px"/>
												</template>
												<user-card :user-id="commentRow.replyToUserId"></user-card>
											</el-popover>
											<div v-if="commentRow.replyToIsAdmin" style="padding-top: 10px;margin-right:40px;">
												<el-badge :style="{color: commentRow.replyToNickname === userStore.nickname ? 'var(--el-color-primary)' : undefined}"
												          value="管理员">
													{{ nicknameFilter(commentRow.replyToNickname) }}
												</el-badge>
											</div>
											<div v-else :style="{color: commentRow.replyToNickname === userStore.nickname ? 'var(--el-color-primary)' : undefined}">
												{{ nicknameFilter(commentRow.replyToNickname) }}
											</div>
										</div>
										<div>：</div>
									</div>
								</template>
							</el-table-column>
							<el-table-column align="center" label="" min-width="400" prop="content" show-overflow-tooltip>
								<template v-slot="{row: commentRow}">
									<div class="text-content">{{ commentRow.content }}</div>
								</template>
							</el-table-column>
							<el-table-column :formatter="elTableDateTimeFormatter" align="center" label="" prop="createTime" width="140"></el-table-column>
							<el-table-column v-if="isAdmin()" align="center" label="排序" prop="sort" width="110">
								<template v-slot="{row: commentRow}">
									<el-tooltip :hide-after="0" :show-after="500" content="排序" effect="dark" placement="top">
										{{ commentRow.sort }}
									</el-tooltip>
								</template>
							</el-table-column>
							<el-table-column align="center" fixed="right" width="230">
								<template v-slot="{row: commentRow}">
									<el-tooltip v-if="!commentRow.liked" :content="isVisitor() ? '游客模式下，点赞功能不可用，请注册账号后使用~' : '点赞'" :hide-after="0"
									            :show-after="500" effect="dark" placement="top">
										<el-button v-auth="'sys-topic:likeComment'" :disabled="isVisitor()"
										           :loading="commentLikeButtonLoading[commentRow.id]"
										           plain round size="small"
										           type="primary" @click="likeComment(commentRow)">
											<template #icon>
												<icon name="fa fa-thumbs-o-up"></icon>
											</template>
											{{ commentRow.likeCount }}
										</el-button>
									</el-tooltip>
									<el-tooltip v-else :content="isVisitor() ? '游客模式下，点赞功能不可用，请注册账号后使用~' : '取消点赞'"
									            :hide-after="0" :show-after="500"
									            effect="dark" placement="top">
										<el-button v-auth="'sys-topic:cancelLikeComment'" :disabled="isVisitor()"
										           :loading="commentLikeButtonLoading[commentRow.id]" round size="small"
										           type="primary" @click="cancelLikeComment(commentRow)">
											<template #icon>
												<icon name="fa fa-thumbs-up"></icon>
											</template>
											{{ commentRow.likeCount }}
										</el-button>
									</el-tooltip>
									<el-tooltip
											:content="isVisitor() ? '游客模式下，回复功能不可用，请注册账号后使用~' : '话题已关闭'"
											:disabled="!(isVisitor() || topicRow.isClosed === '1' && !isAdmin())"
											:hide-after="0" :show-after="500"
											effect="dark" placement="top">
										<el-button
												:disabled="isVisitor() || topicRow.isClosed === '1' && !isAdmin()"
												icon="el-icon-ChatRound" plain round size="small" type="primary"
												@click="toReplyComment(commentRow)">回复
										</el-button>
									</el-tooltip>
									<el-dropdown v-if="isAdmin() || userStore.userId === commentRow.userId" style="margin-left: 10px"
									             @command="handleReplyCommand">
										<el-button icon="el-icon-More" plain round size="small"></el-button>
										<template #dropdown>
											<el-dropdown-menu>
												<el-dropdown-item v-if="isAdmin()" :command="{type: 'sort', data: commentRow}"
												                  icon="el-icon-Sort">
													排序
												</el-dropdown-item>
												<el-dropdown-item v-if="isAdmin()" :command="{type: 'edit', data: commentRow}"
												                  icon="el-icon-Edit">
													编辑
												</el-dropdown-item>
												<el-tooltip v-if="isAdmin() || userStore.userId === commentRow.userId"
												            :disabled="isAdmin() || topicRow.isClosed === '0'"
												            :hide-after="0" :show-after="500" content="话题已关闭" disabled effect="dark"
												            placement="top">
													<span>
														<el-dropdown-item :command="{type: 'delete', data: commentRow}"
														                  :disabled="!isAdmin() && topicRow.isClosed === '1'"
														                  icon="el-icon-Delete">
															删除
														</el-dropdown-item>
													</span>
												</el-tooltip>
											</el-dropdown-menu>
										</template>
									</el-dropdown>
								</template>
							</el-table-column>
						</el-table>
						<cus-pagination
								v-show="refs['replyPage-' + topicRow.id] && refs['replyPage-' + topicRow.id].total > refs['replyPage-' + topicRow.id].pageSize_"
								:ref="'replyPage-' + topicRow.id"
								v-model="topicRow.replyList"
								v-model:loading="replyTableLoading[topicRow.id]"
								:pageSize="10"
								:params="{currentUserId: userStore.userId, topicId_eq: topicRow.id, onlyMe: topicRow.onlyMe, userId: userStore.userId}"
								show-refresh
								simple
								url="/system/sys-topic/readOnly/pageTopicComment"/>
					</div>
				</template>
			</el-table-column>
			<el-table-column align="center" label="类型" prop="type" width="150">
				<template v-slot="{row: topicRow}">
					<el-tag v-if="topicRow.type === '1'" :effect="topicRow.isClosed === '1' ? 'plain' : 'dark'"
					        type="danger">
						{{ messageTypeFilter(topicRow) }}
					</el-tag>
					<el-tag v-if="topicRow.type === '2'" :effect="topicRow.isClosed === '1' ? 'plain' : 'dark'"
					        :style="{'color': topicRow.isClosed === '1' ? 'rgb(64,158,255)' : 'white',
						        'background': topicRow.isClosed === '1' ? '' : 'rgb(64,158,255)',
						        'border-color': topicRow.isClosed === '1' ? 'rgba(64,158,255,0.5)' : 'rgb(64,158,255)'}">
						{{ messageTypeFilter(topicRow) }}
					</el-tag>
					<el-tag v-if="topicRow.type === '3'" :effect="topicRow.isClosed === '1' ? 'plain' : 'dark'" type="success">
						{{ messageTypeFilter(topicRow) }}
					</el-tag>
					<el-tag v-if="topicRow.type === '4'" :effect="topicRow.isClosed === '1' ? 'plain' : 'dark'" type="warning">
						{{ messageTypeFilter(topicRow) }}
					</el-tag>
					<el-tag v-if="topicRow.type === '5'" :effect="topicRow.isClosed === '1' ? 'plain' : 'dark'">
						{{ messageTypeFilter(topicRow) }}
					</el-tag>
					<el-tag v-if="topicRow.type === '6'" :effect="topicRow.isClosed === '1' ? 'plain' : 'dark'"
					        :style="{'color': topicRow.isClosed === '1' ? 'rgb(255,105,180)' : 'white',
						        'background': topicRow.isClosed === '1' ? '' : 'rgb(255,105,180)',
						        'border-color': topicRow.isClosed === '1' ? 'rgba(255,105,180,0.5)' : 'rgb(255,105,180)'}">
						{{ messageTypeFilter(topicRow) }}
					</el-tag>
					<el-tag v-if="topicRow.type === '0'" :effect="topicRow.isClosed === '1' ? 'plain' : 'dark'" type="info">
						{{ messageTypeFilter(topicRow) }}
					</el-tag>
				</template>
			</el-table-column>
			<el-table-column align="center" label="标题" min-width="100" prop="title" show-overflow-tooltip>
				<template v-slot="scope">
					<div v-if="scope.row.sort < MAX_INTEGER" style="padding-top: 10px">
						<el-badge value="置顶">{{ scope.row.title }}</el-badge>
					</div>
					<span v-else>{{ scope.row.title }}</span>
				</template>
			</el-table-column>
			<el-table-column align="center" label="内容" min-width="150" prop="content" show-overflow-tooltip>
				<template v-slot="{row: topicRow}">
					<div class="text-content">{{ topicRow.content }}</div>
				</template>
			</el-table-column>
			<el-table-column align="center" label="用户昵称" prop="nickname" width="200">
				<template v-slot="{row: topicRow}">
					<div style="display: flex;justify-content: center;align-items: end">
						<el-popover :persistent="false" :show-after="300" placement="left" trigger="hover" width="450">
							<template #reference>
								<el-image :src="handleAvatarUrl(topicRow.avatar) || IMAGE_URL.defaultAvatar"
								          style="margin-right: 5px;cursor: pointer;width: auto;height: 25px;border-radius: 5px"/>
							</template>
							<user-card :user-id="topicRow.userId"></user-card>
						</el-popover>
						<div v-if="topicRow.isAdmin" style="padding-top: 10px">
							<el-badge value="管理员">{{ topicRow.nickname }}</el-badge>
						</div>
						<div v-else>{{ topicRow.nickname }}</div>
					</div>
				</template>
			</el-table-column>
			<el-table-column :formatter="elTableDateTimeFormatter" align="center" label="创建时间" prop="createTime" width="170"></el-table-column>
			<el-table-column v-if="isAdmin()" align="center" label="排序" prop="sort" width="110"></el-table-column>
			<el-table-column :label="String($t('table.actions'))" align="center" fixed="right" width="230">
				<template v-slot="{row: topicRow}">
					<el-tooltip v-if="!topicRow.liked"
					            :content="isVisitor() ? '游客模式下，点赞功能不可用，请注册账号后使用~' : '点赞'"
					            :hide-after="0" :show-after="500"
					            effect="dark" placement="top">
						<el-button v-auth="'sys-topic:likeTopic'" :disabled="isVisitor()"
						           :loading="topicLikeButtonLoading[topicRow.id]" plain round
						           size="small" type="primary" @click="likeTopic(topicRow)">
							<template #icon>
								<icon name="fa fa-thumbs-o-up"></icon>
							</template>
							{{ topicRow.likeCount }}
						</el-button>
					</el-tooltip>
					<el-tooltip v-else :content="isVisitor() ? '游客模式下，点赞功能不可用，请注册账号后使用~' : '取消点赞'"
					            :hide-after="0" :show-after="500" effect="dark"
					            placement="top">
						<el-button v-auth="'sys-topic:cancelLikeTopic'" :disabled="isVisitor()"
						           :loading="topicLikeButtonLoading[topicRow.id]" round
						           size="small" type="primary" @click="cancelLikeTopic(topicRow)">
							<template #icon>
								<icon name="fa fa-thumbs-up"></icon>
							</template>
							{{ topicRow.likeCount }}
						</el-button>
					</el-tooltip>
					<el-tooltip :content="isVisitor() ? '游客模式下，评论功能不可用，请注册账号后使用~' : '话题已关闭'"
					            :disabled="!(isVisitor() || topicRow.isClosed === '1' && !isAdmin())"
					            :hide-after="0" :show-after="500" effect="dark"
					            placement="top">
						<el-button :disabled="isVisitor() || topicRow.isClosed === '1' && !isAdmin()"
						           icon="el-icon-ChatRound" plain round size="small" type="primary"
						           @click="toReplyTopic(topicRow)">评论
						</el-button>
					</el-tooltip>
					<el-dropdown v-if="isAdmin() || userStore.userId === topicRow.userId" style="margin-left: 10px"
					             @command="handleMessageCommand">
						<el-button icon="el-icon-MoreFilled" plain round size="small"></el-button>
						<template #dropdown>
							<el-dropdown-menu>
								<el-dropdown-item
										v-if="isAdmin() && topicRow.isClosed === '1'"
										:command="{type: 'open', data: topicRow}" icon="el-icon-ChatDotSquare">
									开启话题
								</el-dropdown-item>
								<el-dropdown-item
										v-if="isAdmin() && topicRow.isClosed === '0'"
										:command="{type: 'close', data: topicRow}" icon="el-icon-CircleClose">
									关闭话题
								</el-dropdown-item>
								<el-dropdown-item v-if="isAdmin()" :command="{type: 'sort', data: topicRow}" icon="el-icon-Sort">
									排序
								</el-dropdown-item>
								<el-dropdown-item v-if="isAdmin() || userStore.userId === topicRow.userId" :command="{type: 'edit', data: topicRow}" icon="el-icon-Edit">
									编辑
								</el-dropdown-item>
								<el-tooltip v-if="isAdmin() || userStore.userId === topicRow.userId" :disabled="isAdmin() || topicRow.isClosed === '0'" :hide-after="0"
								            :show-after="500" content="话题已关闭" effect="dark" placement="top">
									<span>
										<el-dropdown-item :command="{type: 'delete', data: topicRow}"
										                  :disabled="!isAdmin() && topicRow.isClosed === '1'" icon="el-icon-Delete">
											删除
										</el-dropdown-item>
									</span>
								</el-tooltip>
							</el-dropdown-menu>
						</template>
					</el-dropdown>
				</template>
			</el-table-column>
		</el-table>
		<cus-pagination id="topic-pagination" ref="pageRef" v-model="tableData" v-model:loading="topicTableLoading" :pageSize="10" :params="params"
		                url="/system/sys-topic/readOnly/pageSysTopic"/>

		<!-- 对话框（话题新增、修改） -->
		<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="true" :title="dialogTitle"
		           append-to-body center class="cus-dialog" destroy-on-close draggable width="50%">
			<div style="text-align: center">
				<el-form ref="editFormRef" :model="message" :rules="rules" label-width="auto">
					<el-form-item label="话题类型" prop="type">
						<business-code-select v-model="message.type" :hide-value-array="isAdmin() ? undefined : ['6']" clearable code-type="topicType" filterable
						                      force-string-value/>
					</el-form-item>
					<el-form-item label="标题" prop="title">
						<el-input v-model="message.title" clearable maxlength="100" show-word-limit/>
					</el-form-item>
					<el-form-item v-if="isAdmin()" label="排序" prop="sort">
						<el-input-number v-model="message.sort" :max="MAX_INTEGER" :min="1" :step="1" controls-position="right" step-strictly/>
					</el-form-item>
					<el-form-item label="内容" prop="content">
						<el-input v-model="message.content" :autosize="{ minRows: 10 }" clearable maxlength="1000" show-word-limit type="textarea"/>
					</el-form-item>
				</el-form>
			</div>
			<template #footer>
				<el-button v-auth="'sys-topic:saveTopic'" icon="el-icon-CircleCheck" type="primary" @click="saveMessage">
					保存
				</el-button>
				<el-button icon="el-icon-CircleClose" type="warning" @click="dialogVisible = false">
					取消
				</el-button>
			</template>
		</el-dialog>

		<!-- 对话框（评论新增、修改） -->
		<el-dialog v-model="replyDialogVisible" :close-on-click-modal="false" :close-on-press-escape="true"
		           :title="replyDialogTitle" append-to-body center class="cus-dialog" destroy-on-close draggable
		           width="50%">
			<el-form ref="replyFormRef" :model="messageReply" :rules="replyRules" label-width="auto">
				<el-form-item label="内容" prop="content">
					<el-input ref="commentInputRef" v-model="messageReply.content" :autosize="{ minRows: 10 }" clearable maxlength="1000" show-word-limit
					          type="textarea"></el-input>
				</el-form-item>
			</el-form>
			<template #footer>
				<el-button v-auth="'sys-topic:saveTopicComment'" icon="el-icon-CircleCheck" type="primary" @click="saveReply">
					保存
				</el-button>
				<el-button icon="el-icon-CircleClose" type="warning" @click="replyDialogVisible = false">
					取消
				</el-button>
			</template>
		</el-dialog>

	</div>
</template>

<script lang="ts" name="Topic" setup>

import {useUserStore} from '@/stores/modules/user.store'
import {
	elTableDateTimeFormatter,
	focusFormErrorElement,
	getBusinessCodeName,
	handleAvatarUrl,
	initTableIndex,
	messageError,
	messageSuccess
} from '@/utils/commonUtil'
import {nextTick, onActivated, onMounted, reactive, ref, watch} from 'vue'
import type {FormInstance, FormRules, InputInstance, TableInstance} from 'element-plus'
import {ElMessageBox} from 'element-plus'
import {
	cancelLikeCommentApi,
	cancelLikeTopicApi,
	deleteTopicApi,
	deleteTopicCommentApi,
	getLikeCountByCommentIdApi,
	getLikeCountByTopicIdApi,
	likeCommentApi,
	likeTopicApi,
	modifyTopicCommentSortApi,
	modifyTopicSortApi,
	saveTopicApi,
	saveTopicCommentApi,
	toggleTopicClosedApi
} from '@/api/system/topic.api'
import {useI18n} from 'vue-i18n'
import {debounce, type DebouncedFunc, toSafeInteger} from 'lodash-es'
import BusinessCodeSelect from '@/components/business-code-select.vue'
import CusTableTitle from '@/components/cus-table-title.vue'
import CusPagination from '@/components/cus-pagination.vue'
import {useRefs} from '@/utils/vue3Util'
import {calcMaxHeight} from '@/utils/layoutUtil'
import {useEventListener} from '@vueuse/core'
import {onBeforeRouteLeave} from 'vue-router'
import Icon from '@/components/icon.vue'
import {useWebConfigStore} from '@/stores/modules/webConfig.store'
import {isAdmin, isVisitor} from '@/utils/authUtil'
import {IMAGE_URL, MAX_INTEGER} from '@/utils/constantsUtil'
import BusinessCodeRadio from '@/components/business-code-radio.vue'
import UserCard from '@/views/profile/components/UserCard.vue'
import CusForm from '@/components/cus-form.vue'

interface MessageCommand {
	type: 'edit' | 'delete' | 'open' | 'close' | 'sort'
	data: SysTopicRow
}

interface ReplyCommand {
	type: 'sort' | 'edit' | 'delete'
	data: SysTopicCommentRow
}

const userStore = useUserStore()
const webConfigStore = useWebConfigStore()
const {t} = useI18n()

let refs: Record<string, any>

const pageRef = ref()
const editFormRef = ref<FormInstance>()
const replyFormRef = ref<FormInstance>()
const topicTableRef = ref<TableInstance>()
const commentInputRef = ref<InputInstance>()

const topicTableLoading = ref<boolean>(false)
const replyTableLoading = ref<Record<number, boolean>>({})
const topicLikeButtonLoading = ref<Record<number, boolean>>({})
const commentLikeButtonLoading = ref<Record<number, boolean>>({})
const tableMaxHeight = ref<number>(800)

// 计算表格最大高度
const getTableMaxHeight: DebouncedFunc<() => typeof getTableMaxHeight> = debounce(() => {
	tableMaxHeight.value = calcMaxHeight('#topic-form', '#topic-table-title', '#topic-pagination')
	return getTableMaxHeight
}, 100, {
	leading: true,
	trailing: false,
	maxWait: 100
})

const nicknameFilter = (nickname: string) => {
	return nickname === userStore.nickname ? '我' : nickname
}

const messageTypeFilter = (message: SysTopic) => {
	let topicType = getBusinessCodeName('topicType', message.type!, true)
	if (message.isClosed === '1') {
		topicType += ' (已关闭)'
	}
	return topicType
}

const params = reactive<SearchTopicRequest>({
	currentUserId: userStore.userId,
	type_eq: undefined,
	title_like: undefined,
	content_like: undefined,
	onlyMe: false,
	isClosed_eq: undefined,
	userId_eq: undefined,
	nickname_like: undefined,
	sortOrder: 'time'
})

const message = reactive<SysTopic>({
	id: undefined,
	userId: undefined,
	nickname: undefined,
	type: undefined,
	title: undefined,
	content: undefined,
	isClosed: '0',
	sort: MAX_INTEGER,
	operator: undefined,
	createTime: undefined,
	updateTime: undefined
})

const tableData = ref<SysTopicRow[]>([])

const messageReply = reactive<SysTopicComment>({
	id: undefined,
	topicId: undefined,
	parentId: undefined,
	userId: undefined,
	nickname: undefined,
	replyToUserId: undefined,
	replyToNickname: undefined,
	content: undefined,
	sort: undefined,
	operator: undefined,
	createTime: undefined,
	updateTime: undefined
})

const dialogTitle = ref<string>()
const replyDialogTitle = ref<string>()
const dialogVisible = ref<boolean>(false)
const replyDialogVisible = ref<boolean>(false)

const rules = reactive<FormRules>({
	type: [
		{required: true, message: '请选择话题类型', trigger: 'change'}
	],
	title: [
		{required: true, message: '请输入标题', trigger: 'change'}
	],
	sort: [
		{required: true, message: '请输入排序', trigger: 'change', type: 'number'},
		{min: 1, max: MAX_INTEGER, message: `最小值为1，最大值为${MAX_INTEGER}`, trigger: 'change', type: 'number'}
	],
	content: [
		{required: true, message: '请输入内容', trigger: 'change'}
	]
})

const replyRules = reactive<FormRules>({
	content: [
		{required: true, message: '请输入回复内容', trigger: 'change'},
		{max: 1000, message: '长度不超过20字符', trigger: 'change'}
	]
})

watch(tableData, val => {
	val.forEach(row => {
		// 添加前端需要的属性
		Reflect.set(row, 'replyList', [])
		Reflect.set(row, 'loading', false)
		Reflect.set(row, 'onlyMe', false)
		replyTableLoading.value[row.id!] = false
	})
}, {deep: false})

const onlyMeChanged = (val: boolean) => {
	if (val) {
		params.userId_eq = userStore.userId
		params.nickname_like = undefined
	} else {
		params.userId_eq = undefined
	}
	handleSearch()
}

const replyOnlyMeChanged = (val: boolean, messageId: number) => {
	nextTick(() => {
		refs['replyPage-' + messageId].reload()
	})
}

const showAllComment = () => {
	tableData.value.forEach(row => {
		topicTableRef.value?.toggleRowExpansion(row, true)
	})
}

const hideAllComment = () => {
	tableData.value.forEach(row => {
		topicTableRef.value?.toggleRowExpansion(row, false)
	})
}

const handleSearch = () => {
	pageRef.value.reload()
}

const resetParams = () => {
	params.currentUserId = userStore.userId
	params.type_eq = undefined
	params.title_like = undefined
	params.content_like = undefined
	params.onlyMe = false
	params.isClosed_eq = undefined
	params.userId_eq = undefined
	params.nickname_like = undefined
	// params.sortOrder = 'time'
}

const resetSearch = () => {
	resetParams()
	handleSearch()
}

const resetMessage = () => {
	message.id = undefined
	message.userId = undefined
	message.nickname = undefined
	message.type = undefined
	message.title = undefined
	message.content = undefined
	message.isClosed = '0'
	message.sort = MAX_INTEGER
	message.operator = undefined
	message.createTime = undefined
	message.updateTime = undefined
}

const resetMessageReply = () => {
	messageReply.id = undefined
	messageReply.topicId = undefined
	messageReply.parentId = undefined
	messageReply.userId = undefined
	messageReply.nickname = undefined
	messageReply.replyToUserId = undefined
	messageReply.replyToNickname = undefined
	messageReply.content = undefined
	messageReply.operator = undefined
	messageReply.createTime = undefined
	messageReply.updateTime = undefined
}

const toAdd = () => {
	resetMessage()
	dialogTitle.value = '新话题'
	dialogVisible.value = true
	nextTick(() => {
		editFormRef.value!.clearValidate()
	})
}

const toUpdateMessage = (row: SysTopicRow) => {
	resetMessage()
	Object.assign(message, JSON.parse(JSON.stringify(row)))
	dialogVisible.value = true
	dialogTitle.value = '编辑话题'
	nextTick(() => {
		editFormRef.value!.clearValidate()
	})
}

const saveMessage = () => {
	editFormRef.value!.validate(isValid => {
		if (isValid) {
			message.userId = message.userId || userStore.userId
			message.nickname = message.nickname || userStore.nickname
			saveTopicApi(message).then(() => {
				messageSuccess('保存成功')
				dialogVisible.value = false
				pageRef.value.buildData()
			})
		} else {
			focusFormErrorElement()
		}
	})
}

const deleteMessage = (row: SysTopicRow) => {
	deleteTopicApi(row.id!).then(() => {
		messageSuccess(t('successMessage.delete'))
		pageRef.value.buildData()
	})
}

const toReplyTopic = (row: SysTopicRow) => {
	resetMessageReply()
	messageReply.topicId = row.id
	messageReply.parentId = 0
	messageReply.replyToUserId = row.userId
	messageReply.replyToNickname = row.nickname
	messageReply.sort = MAX_INTEGER
	replyDialogTitle.value = '回复：' + (row.content?.length! > 20 ? row.content?.substring(0, 20) + '...' : row.content)
	replyDialogVisible.value = true
	nextTick(() => {
		replyFormRef.value!.clearValidate()
		nextTick(() => {
			commentInputRef.value!.focus()
		})
	})
}

const toReplyComment = (row: SysTopicCommentRow) => {
	resetMessageReply()
	messageReply.topicId = row.topicId
	messageReply.parentId = row.id
	messageReply.replyToUserId = row.userId
	messageReply.replyToNickname = row.nickname
	messageReply.sort = MAX_INTEGER
	replyDialogTitle.value = '回复：' + (row.content?.length! > 20 ? row.content?.substring(0, 20) + '...' : row.content)
	replyDialogVisible.value = true
	nextTick(() => {
		replyFormRef.value!.clearValidate()
		nextTick(() => {
			commentInputRef.value!.focus()
		})
	})
}

const toUpdateReply = (row: SysTopicCommentRow) => {
	resetMessageReply()
	Object.assign(messageReply, JSON.parse(JSON.stringify(row)))
	replyDialogTitle.value = '编辑评论'
	replyDialogVisible.value = true
	nextTick(() => {
		replyFormRef.value!.clearValidate()
	})
}

const saveReply = () => {
	replyFormRef.value!.validate(isValid => {
		if (isValid) {
			messageReply.userId = messageReply.userId || userStore.userId
			messageReply.nickname = messageReply.nickname || userStore.nickname
			saveTopicCommentApi(messageReply).then(() => {
				if (messageReply.id) {
					messageSuccess('评论已更新')
				} else {
					messageSuccess('评论成功')
				}
				replyDialogVisible.value = false
				if (refs['replyPage-' + messageReply.topicId]) {
					refs['replyPage-' + messageReply.topicId].reload()
				} else {
					// 展开评论
					topicTableRef.value!.toggleRowExpansion(tableData.value.find(row => row.id === messageReply.topicId), true)
				}
			})
		} else {
			focusFormErrorElement()
		}
	})
}

const deleteMessageReply = (row: SysTopicCommentRow) => {
	deleteTopicCommentApi(row.id!).then(() => {
		messageSuccess(t('successMessage.delete'))
		refs['replyPage-' + row.topicId].reload()
	})
}

const handleMessageCommand = (command: MessageCommand) => {
	const contentDisplayed = command.data.content?.length! > 100 ? command.data.content?.substring(0, 100) + '...' : command.data.content
	switch (command.type) {
		case 'open':
			ElMessageBox.confirm(contentDisplayed, '开启话题后开放评论', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning',
				draggable: true
			}).then(() => {
				toggleTopicClosedApi({topicId: command.data.id!, isClosed: '0'}).then(() => {
					messageSuccess('话题已开启')
					pageRef.value.buildData()
				})
			}).catch(() => {
			})
			break
		case 'close':
			ElMessageBox.confirm(contentDisplayed, '关闭话题后禁止评论', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning',
				draggable: true
			}).then(() => {
				toggleTopicClosedApi({topicId: command.data.id!, isClosed: '1'}).then(() => {
					messageSuccess('话题已关闭')
					pageRef.value.buildData()
				})
			}).catch(() => {
			})
			break
		case 'sort':
			ElMessageBox.prompt(`请输入排序值，越小越靠前（最小值：1，最大值：${MAX_INTEGER}）`, '修改话题排序', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				inputPattern: /^[1-9]\d*$/,
				inputErrorMessage: '请输入正整数',
				inputValue: String(command.data.sort),
				draggable: true
			}).then(({value}) => {
				if (toSafeInteger(value) < 1) {
					messageError('指定的顺序（' + value + '）小于最小值（1）')
					return
				}
				if (toSafeInteger(value) > MAX_INTEGER) {
					messageError(`指定的顺序（${value}）超过最大值（${MAX_INTEGER}）`)
					return
				}
				modifyTopicSortApi({topicId: command.data.id!, sort: toSafeInteger(value)}).then(() => {
					messageSuccess('排序已保存')
					pageRef.value.buildData()
				})
			}).catch(() => {
			})
			break
		case 'edit':
			toUpdateMessage(command.data)
			break
		case 'delete':
			ElMessageBox.confirm(contentDisplayed, '删除该话题和所有评论？', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning',
				draggable: true
			}).then(() => {
				deleteMessage(command.data)
			}).catch(() => {
			})
			break
	}
}

const handleReplyCommand = (command: ReplyCommand) => {
	switch (command.type) {
		case 'sort':
			ElMessageBox.prompt(`请输入排序值，越小越靠前（最小值：1，最大值：${MAX_INTEGER}）`, '修改评论排序', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				inputPattern: /^[1-9]\d*$/,
				inputErrorMessage: '请输入正整数',
				inputValue: String(command.data.sort),
				draggable: true
			}).then(({value}) => {
				if (toSafeInteger(value) < 1) {
					messageError('指定的顺序（' + value + '）小于最小值（1）')
					return
				}
				if (toSafeInteger(value) > MAX_INTEGER) {
					messageError(`指定的顺序（${value}）超过最大值（${MAX_INTEGER}）`)
					return
				}
				modifyTopicCommentSortApi({topicCommentId: command.data.id!, sort: toSafeInteger(value)}).then(() => {
					messageSuccess('排序已保存')
					refs['replyPage-' + command.data.topicId].reload()
				})
			}).catch(() => {
			})
			break
		case 'edit':
			toUpdateReply(command.data)
			break
		case 'delete':
			const contentDisplayed = command.data.content?.length! > 100 ? command.data.content?.substring(0, 100) + '...' : command.data.content
			ElMessageBox.confirm(contentDisplayed, '删除该评论？', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning',
				draggable: true
			}).then(() => {
				deleteMessageReply(command.data)
			}).catch(() => {
			})
			break
	}
}

const likeTopic = (row: SysTopicRow) => {
	topicLikeButtonLoading.value[row.id!] = true
	likeTopicApi({
		topicId: row.id!,
		userId: userStore.userId!
	}).then(() => {
		getLikeCountByTopicIdApi(row.id!).then(res => {
			row.likeCount = res.data
			row.liked = true
			// messageSuccess('点赞成功')
		}).finally(() => {
			topicLikeButtonLoading.value[row.id!] = false
		})
	}).finally(() => {
		topicLikeButtonLoading.value[row.id!] = false
	})
}

const cancelLikeTopic = (row: SysTopicRow) => {
	topicLikeButtonLoading.value[row.id!] = true
	cancelLikeTopicApi({
		topicId: row.id!,
		userId: userStore.userId!
	}).then(() => {
		getLikeCountByTopicIdApi(row.id!).then(res => {
			row.likeCount = res.data
			row.liked = false
			// messageSuccess('已取消点赞')
		}).finally(() => {
			topicLikeButtonLoading.value[row.id!] = false
		})
	}).finally(() => {
		topicLikeButtonLoading.value[row.id!] = false
	})
}

const likeComment = (row: SysTopicCommentRow) => {
	commentLikeButtonLoading.value[row.id!] = true
	likeCommentApi({
		topicCommentId: row.id!,
		userId: userStore.userId!
	}).then(() => {
		getLikeCountByCommentIdApi(row.id!).then(res => {
			row.likeCount = res.data
			row.liked = true
			// messageSuccess('点赞成功')
		}).finally(() => {
			commentLikeButtonLoading.value[row.id!] = false
		})
	}).finally(() => {
		commentLikeButtonLoading.value[row.id!] = false
	})
}

const cancelLikeComment = (row: SysTopicCommentRow) => {
	commentLikeButtonLoading.value[row.id!] = true
	cancelLikeCommentApi({
		topicCommentId: row.id!,
		userId: userStore.userId!
	}).then(() => {
		getLikeCountByCommentIdApi(row.id!).then(res => {
			row.likeCount = res.data
			row.liked = false
			// messageSuccess('已取消点赞')
		}).finally(() => {
			commentLikeButtonLoading.value[row.id!] = false
		})
	}).finally(() => {
		commentLikeButtonLoading.value[row.id!] = false
	})
}

onMounted(() => {
	refs = useRefs()
	useEventListener(window, 'resize', getTableMaxHeight()!)
})

// 该页面开启缓存且首次或后续进入时执行，刷新页面不执行
onActivated(() => {
	useEventListener(window, 'resize', getTableMaxHeight()!)
})

onBeforeRouteLeave(() => {
	window.removeEventListener('resize', getTableMaxHeight)
})

</script>

<style lang="scss" scoped>
.text-content {
	white-space: pre-wrap;
	text-align: left;
}

:deep(.topic-row) {
	background-color: v-bind('webConfigStore.layout.isDark ? "rgba(0, 0, 0, 0.5)": undefined');

	.el-table-fixed-column--right {
		background-color: v-bind('webConfigStore.layout.isDark ? "rgba(0, 0, 0, 0.5)": undefined');
	}

	.el-table-fixed-column--left {
		background-color: v-bind('webConfigStore.layout.isDark ? "rgba(0, 0, 0, 0.5)": undefined');
	}
}

:deep(.comment-row) {
	background-color: v-bind('webConfigStore.layout.isDark ? "rgba(255, 255, 255, 0.03)": undefined');

	.el-table-fixed-column--right {
		background-color: v-bind('webConfigStore.layout.isDark ? "rgba(255, 255, 255, 0.03)": undefined');
	}

	.el-table-fixed-column--left {
		background-color: v-bind('webConfigStore.layout.isDark ? "rgba(255, 255, 255, 0.03)": undefined');
	}
}
</style>
